CC:=gcc
CFLAGS:=-Wall -g

LEX_FILE:=src/lex/lexicalAnalyzer.lex
LEX_SRC:=$(patsubst src/lex/%.lex,%.c,$(LEX_FILE))
LEX_OBJECTS:=$(patsubst src/lex/%.lex,%.o,$(LEX_FILE))
LEX_OBJECTS_DIR:=$(patsubst src/lex/%.lex,objects/%.o,$(LEX_FILE))
LEX_INCLUDE_DIR:=$(patsubst src/lex/%.lex,include/%.h,$(LEX_FILE))

YACC_FILE:=src/yacc/syntacticAnalyzer.y
YACC_SRC:=$(patsubst src/yacc/%.y,%.c,$(YACC_FILE))
YACC_OBJECTS:=$(patsubst src/yacc/%.y,%.o,$(YACC_FILE))
YACC_OBJECTS_DIR:=$(patsubst src/yacc/%.y,objects/%.o,$(YACC_FILE))
YACC_INCLUDE_DIR:=$(patsubst src/yacc/%.y,include/%.h,$(YACC_FILE))

OBJECTS:=$(patsubst src/%.c,%.o,$(wildcard src/*.c))
OBJECTS:=$(subst $(LEX_OBJECTS),,$(OBJECTS))
OBJECTS:=$(subst $(YACC_OBJECTS),,$(OBJECTS))
OBJECTS_DIR:=$(patsubst %.o,objects/%.o,$(OBJECTS))

LIB_LIST_SRC:=$(wildcard src/list/*.c)
LIB_LIST_OBJECTS:=$(patsubst src/list/%.c,%.o,$(LIB_LIST_SRC))
LIB_LIST:=libmylist.a


INC_PATH:=include/
VPATH:=include:src:src/lex:src/yacc:objects:lib:bin
LFLAGS:=-L lib/ -lmylist

ifdef debug
  DEBUG=--debug
endif

# if looking for library flags, try command "${libname}-config --ldflags"
# or "pkg-config ${libname} --libs"

all : main

# the order is important: we have to create the sources out of lex files first
# because of the include file generated
main : $(LEX_OBJECTS) $(YACC_OBJECTS) $(OBJECTS) $(LIB_LIST)
	$(CC) $(CFLAGS) $(LEX_OBJECTS_DIR) $(YACC_OBJECTS_DIR) $(OBJECTS_DIR) $(LFLAGS) -o $@
	mv $@ bin/

$(LIB_LIST) : $(LIB_LIST_SRC)
	$(CC) $(CFLAGS) -I $(INC_PATH) -c $(LIB_LIST_SRC)
	ar rcs $(LIB_LIST) $(LIB_LIST_OBJECTS)
	mv $(LIB_LIST) lib/
	rm $(LIB_LIST_OBJECTS)


%.o : %.c
	$(CC) $(CFLAGS)  -I $(INC_PATH) -c $<
	mv $@ objects/


src/$(LEX_SRC) : $(LEX_FILE) $(YACC_FILE) $(YACC_SRC)
# Indeed lex sources rely on yacc header files
# We must rebuild the lex each time the YACC_FILE is altered,
# and the YACC_SRC has to be built
	flex  --outfile=$(LEX_SRC) $(DEBUG) --header-file=$(LEX_INCLUDE_DIR) $(LEX_FILE)
	mv $(LEX_SRC) src/

src/$(YACC_SRC) : $(YACC_FILE)
	bison --output=$(YACC_SRC) $(DEBUG) -v --defines=$(YACC_INCLUDE_DIR) $(YACC_FILE)
	mv $(YACC_SRC) src/


archive : 
	tar -cvf archive.tar makefile src/ include/
	tar -rvf archive.tar --no-recursion bin objects lib 
	gzip archive.tar

TAGS : 
	find . -type f -iname "*.h" -or -iname "*.cpp" -or -iname "*.hpp" | xargs etags -a 

clean :
	rm -f objects/*.o bin/* archive.tar.gz  $(LEX_INCLUDE_DIR) $(YACC_INCLUDE_DIR) src/$(LEX_SRC) src/$(YACC_SRC) lib/* 
